package main

import (
	"fmt"
	"gitee.com/huanminabc/go-utils/cmd"
	"gitee.com/huanminabc/go-utils/common"
	"go-LineScriptCommand/command"
	"go-LineScriptCommand/container"
	_ "go-LineScriptCommand/fun_Implement"
	"go-LineScriptCommand/global"
	"os"
	"os/signal"
	"strings"
	"syscall"
	"time"
)

// 获取之前的命令输入的结果, 比如 cat a.txt|grep "a"  获取到的是a.txt的内容
// 通过cat .gitignore | go run main.go可以进行测试
func getPrePipeValue() {
	inputChan := make(chan string)
	var prePipeValue strings.Builder
	cmd.RegisterReadStdin("go-LineScriptCommand-main", func(stdin string) {
		inputChan <- stdin
	})

	//5毫秒超时,意思就是在程序启动后的5毫秒如果没有输入,那么就退出
	timerDuration := 5 * time.Millisecond
	timeout := time.NewTimer(timerDuration)
	defer timeout.Stop()
loop: //跳出多层循环
	for {
		timeout.Reset(timerDuration) //每次刷新重置
		select {
		case input := <-inputChan:
			prePipeValue.WriteString(input + global.LineBreak)
		case <-timeout.C: // 设置chan超时时间10ms
			// 超时了，没有接收到有命令输入
			//fmt.Println("超时了，没有接收到有命令输入")
			break loop //超时退出
		}
	}
	//删除
	cmd.UnRegisterReadStdin("go-LineScriptCommand-main")

	//判断stdin
	if prePipeValue.Len() == 0 {
		return
	}
	stdin := prePipeValue.String()
	//去掉最后所有的换行符
	stdin = strings.TrimRight(stdin, global.LineBreak)

	//识别是否是数字
	if common.IsNumber(stdin) {
		//将数据放入到管道中
		data := container.NewPipelineData(stdin)
		container.RegisterPipelineData(data)
	} else {
		stdin = global.AddStrSymbol(stdin)
		//将数据放入到管道中
		data := container.NewPipelineData(stdin)
		container.RegisterPipelineData(data)
	}
}

func main() {
	// 设置一个通道来接收中断信号
	interrupt := make(chan os.Signal, 1)
	signal.Notify(interrupt, syscall.SIGINT)
	strings__ := os.Args[1:]
	go func() {
		//因为-books内部使用了输入,导致被getPrePipeValue获取到了,所以这里要判断一下
		if len(strings__) == 1 && !(strings.HasSuffix(strings__[0], "-books") || strings.HasSuffix(strings__[0], "--books")) {
			cmd.ReadStdinSustain() //开启一个协程,持续读取控制台输入
			//获取之前的命令输入的结果,放入到管道中
			getPrePipeValue()
		}
		//入口
		command.ExecuteCommand()
		interrupt <- syscall.SIGTERM //正常退出
	}()
	// 阻塞，直到接收到中断信号
	var sig = <-interrupt
	//停止接收信号,防止被其他信号处理,确保信号只被处理一次。
	signal.Stop(interrupt)
	// 关闭channel
	close(interrupt)
	//如果不是SIGTERM信号,则退出程序
	if sig != syscall.SIGTERM {
		fmt.Println("正在退出程序...")
		// 在这里执行清理工作，比如关闭文件、数据库连接等
		// ... (清理工作的代码)
		// 退出程序
		os.Exit(0)
	}
}
